var querystring = require('querystring');

exports.login = function(player, req, resp, onHandled) {
    player.action.score = 50;
    player.openid = req.args.openid;
    var uid = player.uid;
    var user = player.user;
    var newVersion = false;
    var now = new Date();
    var nowStamp = now.getStamp();
    var zeroStamp = now.zeroTime().getStamp();

    if (player.status.newRole) {
        //CreateRole|iEventId|iWorldId|iUin|dtEventTime|vClientIp|iRoleId|vRoleName|iJobId|iGender|iLoginWay
        writeRecord(util.format('CreateRole|create|%d|%s|%s|%s|%d|RoleName|0|0|0', 
            config.ServerId, player.openid, Date.stdFormatedString(), player.clientIP, player.uid));
    }
    player.status = {};

    do {
        var authTime = parseInt(req.auth_time);
        if (nowStamp - authTime > 1200) {
            resp.code = 2; resp.desc = 'auth_timeout'; break;
        }

        if( 'string' != typeof(req.args.name) || 'string' != typeof(req.args.headpic) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }
        
        if (gConfGlobal.GameGuardLoginTimes) {
            if (player.getDailyVar('login_times') > gConfGlobal.GameGuardLoginTimes) {
                resp.code = 1; resp.desc = 'except_limit'; break;
            }
        }
        
        if (!user.info.createIP) {
            user.info.createIP = player.clientIP; 
            player.markDirty('info.createIP');
        }

        user.mark.lastIP = player.clientIP;
        player.markDirty('mark.lastIP');
    
        if (player.loginStamp) {
            var onlineTime = Math.max(0, nowStamp - player.loginStamp);
            player.addDailyVar('onlineTime', onlineTime);
            addAttrValue(user.mark, 'online_time', onlineTime);
            player.markDirty('mark.online_time');
            //Login uid loginStamp logoutStamp level ip
            writeAudit(util.format('Login %d %d %d %d %s', uid, player.loginStamp, nowStamp, user.status.level, player.clientIP));
        }
        player.loginStamp = nowStamp;
        player.addDailyVar('login_times', 1);

        var today = common.getDate();

        if( req.args.name ) {
            var obj = querystring.parse('name='+req.args.name);
            req.args.name = obj.name || '';
        }
        
        var infoDirty = false;
        if( !user.mark.rename && req.args.name && req.args.name != user.info.un ) {
            user.info.un = req.args.name;
            infoDirty = true;
        }
        if( !user.mark.rename && req.args.headpic && req.args.headpic != user.info.headpic ) {
            user.info.headpic = req.args.headpic;
            infoDirty = true;
        }

        if( !user.info.hasOwnProperty('platform') ) {
            user.info.platform = '';
            user.info.yellow = 0;
            user.info.blue = 0;
            user.info.yellow_year = 0;
            user.info.blue_year = 0;
            infoDirty = true;
        }

        if (!user.hasOwnProperty('xingzuo_romance')) {
            user.xingzuo_romance = {
                'point' : 0,
                'candy' : 0,
                'pos' : 1,
                'normal' : 0,
                'high' : 0,
            };
            infoDirty = true;
        }

        if (!user.hasOwnProperty('qqpcmgr')) {
            user.qqpcmgr = {
                'new_user_award_time' : 0,
                'sign_count': 0,
            };
            infoDirty = true;
        }
        

        var pf = req.args.pf;
        if( pf && !user.info.platform && (pf == 'qzone' || pf == 'pengyou' || pf == '3366') ) {
            user.info.platform = pf;
            infoDirty = true;
        }

        var userArgs = req.args.user;
        if( common.verifyGatewayAuth(req.args.openid+userArgs, req.args.openkey) || (req.openkey != config.GWAuth) ) {
            try{
                userArgs = JSON.parse(userArgs);
            }catch(e){
                userArgs = null;
            }

            if( userArgs ) {
                if( userArgs.is_blue ) {
                    // 蓝钻
                    user.info.blue = userArgs.is_yellow_vip ? +userArgs.yellow_vip_level : 0;
                    user.info.blue_year= userArgs.is_yellow_year_vip ? 1 : 0;
                }else{
                    // 黄钻
                    user.info.yellow = userArgs.is_yellow_vip ? +userArgs.yellow_vip_level : 0;
                    user.info.yellow_year= userArgs.is_yellow_year_vip ? 1 : 0;
                }

                if( !user.info.via && userArgs.via ) {
                    user.info.via = userArgs.via;
                }

                if( !user.info.invited && userArgs.invited && req.args.invited && !isNaN(req.args.invited) ) {
                    user.info.invited = +req.args.invited;
                }

                if( !user.info.hasOwnProperty('roll') ) {
                    user.info.roll = userArgs.roll ? 1 : 0;
                }

                infoDirty = true;
            }
        }

        player.open_session_key = req.args.open_session_key;

        if( !isNaN(req.args.version) ) {
            if( user.info.version != req.args.version ) {
                newVersion = true;
                user.info.version = req.args.version;
                infoDirty = true;
            }
        }

        if( infoDirty ) {
            player.markDirty('info');
        }
        
        // 任务集市
        if( req.args.app_contract_id && !user.activity.hasOwnProperty('app_contract_id')) {
            user.activity.app_contract_id = req.args.app_contract_id;
            player.markDirty('activity.app_contract_id');

            if( userArgs && userArgs.task_v3 ) {
                user.activity.contract_task_v3 = 1;// 1安装游戏
                user.activity.contract_task_reward_v3 = 0;// 奖励领取步奏

                player.markDirty('activity.contract_task_v3');
                player.markDirty('activity.contract_task_reward_v3');
            }else{
                user.activity.contract_task = 1; // 1安装游戏
                player.markDirty('activity.contract_task');
            }
        }

        if (!user.status.food && user.status.food != 0) {
            user.status.food = 0;
            player.markDirty('status.food');
        }

        // 好友点数
        if (!user.status.hasOwnProperty('friend_point')) {
            user.status.friend_point = 0;
            player.markDirty('status.friend_point');
        }

        if( !user.hasOwnProperty('combine') ) {
            user.combine = { 
                'stone' : 0,      
                'got' : 0,       
                'combined' : 0, 
                'occupying' : 0,
            };

            player.markDirty('combine');
        }

        if( !user.business.hasOwnProperty('back') ) {
            user.business.back = 0; 
            player.markDirty('business.back');
        }

        if( !user.hasOwnProperty('wheel') ) {
            user.wheel = {
                'free':0,               
                'star':0,              
                'star_cash':0,
                'first_start':1,
                'star_cash_total':0, 
            };
            player.markDirty('wheel');
        }
        
        if( !user.hasOwnProperty('league_war') ){
            user.league_war = {            
                'energy' : 0,          
                'energy_time' : 0,    
                'ex_energy_time':0,
                'buy_energy':0,         
                'move_time':0,
                'move':1,
                'glory':0,             
                'grade_level':1,      
                'grade_xp':0,        
            };
            player.markDirty('league_war');
        } else {
            if (!user.league_war.glory && user.league_war.glory != 0) {
                user.league_war.glory = 0;
                player.markDirty('league_war.glory');
            }
        }

        if( !user.league_war.hasOwnProperty('ex_energy_time') ) {
            user.league_war = {            
                'energy' : 0,          
                'energy_time' : 0,    
                'ex_energy_time':0,
                'buy_energy':0,         
                'move_time':0,
                'move':1,
                'glory': user.league_war.glory,             
                'grade_level': user.league_war.grade_level,      
                'grade_xp': user.league_war.grade_xp,        
            };
            player.markDirty('league_war');
        }
        
        if( !user.hasOwnProperty('invest') ) {
           user.invest = {
                'got': 0,
                'invested': 0,
                'time':'',
           };
           player.markDirty('invest');
        }
        
        if( !user.mark.hasOwnProperty('gold') ) {
            user.mark.gold = 0;
            player.markDirty('mark.gold');
        }

        if( !user.hasOwnProperty('boss') ) {
            user.boss = {
                'join': 0,
                'got_reward':0,
                'time':0,
                'inspire':0,
            };
            player.markDirty('boss');
        }

        if( !user.hasOwnProperty('black_shop') ) {
            user.black_shop = {
                'timer' : 0,      
                'sell':{},
            };
            player.markDirty('black_shop');
        }

        if( !user.hasOwnProperty('surprise') ) {
            user.surprise = {
                'grid': 1,              // 格子编号
                'free': 0,              // 使用的免费次数
            };
            player.markDirty('surprise');
        }

        if( !user.activity.hasOwnProperty('limit_buy') ) {
            user.activity.limit_buy = {};
            player.markDirty('activity.limit_buy');
        }
        
        if( !user.hasOwnProperty('tomb') ) {
            user.tomb = {                    
                'kill': [0, 0, 0],         
                'dig': [0, 0, 0],        
                'got': [0, 0, 0],             
            };
            player.markDirty('tomb');
        }

        if( !user.activity.hasOwnProperty('offline_xp') ) {
            user.activity.offline_xp = {
                'level': user.status.level,
                'vip': user.status.vip,
                'time': 0
            };
            player.markDirty('activity.offline_xp');
        }

        if( !user.activity.hasOwnProperty('topone2') ) {
            user.activity.topone2 = {
                'day': 0,
                'vote':0,
            };
            player.markDirty('activity.topone2');
        }

        if( !user.activity.hasOwnProperty('charge') ) {
            user.activity.charge = {
                'cash':0,          
                'time':0,
                'got' : {
                }, 
            };
            player.markDirty('activity.charge');
        }

        if( !user.activity.hasOwnProperty('gentry') ) {
            user.activity.gentry = {
                'cash':0,          
                'time':0,
                'got' :0,
            };
            player.markDirty('activity.gentry');
        }

        if( !user.activity.hasOwnProperty('slot') ) {
            user.activity.slot = {}; 
            player.markDirty('activity.slot');
        }
        
        if( !user.hasOwnProperty('server_war') ) {
            user.server_war = {
                'save_team':0,         
                'support':{},
                'top_reward':0,  
                'count':0,
            }; 
            player.markDirty('server_war');
        }

        if( !user.hasOwnProperty('achievement') ) {
            user.achievement = {
                'stage': 1,
                'goal': {},
                'reserved': {}
            };

            player.markDirty('achievement');
        }

        if( !user.activity.hasOwnProperty('blue_level') ) {
            user.activity.blue_level = 0; 
            player.markDirty('activity.blue_level');
        }

        if( !user.activity.hasOwnProperty('wished') ) {
            user.activity.wished = 0;
            player.markDirty('activity.wished');
        }

        if( !user.hasOwnProperty('forge') ) {
            user.forge =  {           
                'total': 0,      
                'today': 0,     
                'got'  : 0,
            };
            player.markDirty('forge');
        }

        if( !user.hasOwnProperty('lottery') ) {
            user.lottery = {
                'score' : 0,
                'day' : 0,
                'got' : 0,
                'count' : 0,
            }; 
            player.markDirty('lottery');
        }
        
        if( !user.activity.hasOwnProperty('yellow_diamond') ) {
            user.activity.yellow_diamond = {     
                'opened': 0,        
                'time': 0,          
                'got' : 0,
            };
            player.markDirty('activity.yellow_diamond');
        }

        if( !user.activity.hasOwnProperty('five_role_reward') ) {
            user.activity.five_role_reward = 0;
            player.markDirty('activity.five_role_reward');
        }

        if( !user.activity.hasOwnProperty('tower') ) {
            user.activity.tower = 0;
            user.activity.fight_force = 0;
            user.activity.forge_level = {};

            player.markDirty('activity.tower');
            player.markDirty('activity.fight_force');
            player.markDirty('activity.forge_level');
        }

        if( !user.activity.hasOwnProperty('player_level') ) {
            user.activity.player_level = 0;     
            player.markDirty('activity.player_level');
        }

        if( !user.hasOwnProperty('world_boss') ) {
            user.world_boss = {     
                'join': 0,             
                'today_id':0,         
                'got_reward':0,      
                'time':0,           
                'inspire':0,       
            };

            player.markDirty('world_boss');
        }

        if (!user.hasOwnProperty('league_duplicate')) {
            user.league_duplicate = {
                'inspire' : 0,
                'attack_times' : 0,
                'buy_times' : 0,
            };

            player.markDirty('league_duplicate');
        }

        if( !user.activity.hasOwnProperty('group_on') ) {
            user.activity.group_on = {     
                'buy' : 0,
            };
            player.markDirty('activity.group_on');
        }

        if( !user.activity.hasOwnProperty('western') ) {
            user.activity.western = {     
                'time':0,
                'id':1,             
                'cards':[],      
                'opened':[],    
                'back':0,      
            };
            player.markDirty('activity.western');
        }

        if( !user.black_shop.hasOwnProperty('limit_sell') ) {
            user.black_shop.timer = 0; 
            player.markDirty('black_shop.timer');
            user.black_shop.limit_sell = {}; 
            player.markDirty('black_shop.limit_sell');
        }
        
        
        if( !user.activity.hasOwnProperty('wealth') ) {
            user.activity.wealth = {     
                'count' : 0,
                'time' : 0,
            };

            player.markDirty('activity.wealth');
        }

        if( !user.hasOwnProperty('day_wheel') ) {
            user.day_wheel = {     
                'reward_id' : 1,
                'update_count':0,
                'lottery_count':0,
                'free':0,
                'cash':0,
            };
            player.markDirty('day_wheel');
        }

        if( !user.activity.hasOwnProperty('visit_cottage') ) {
            user.activity.visit_cottage = {     
                'count':0,
                'free':0,
                'got':0,
                'cash':0,
                'visit':0,
            };
            player.markDirty('activity.visit_cottage');
        }

        if( !user.activity.hasOwnProperty('pay_rank') ) {
            user.activity.pay_rank = {
                'time' : 0,
                'paid' : {},
                'got' : {},
            };

            player.markDirty('activity.pay_rank');
        }

        if( !user.activity.hasOwnProperty('pay_rank') ) {
            user.activity.pay_rank = {
                'time' : 0,
                'paid' : {},
                'got' : {},
            };

            player.markDirty('activity.pay_rank');
        }

        if( !user.activity.hasOwnProperty('hit_box') ) {
            user.activity.hit_box = {
                'hit' : 0,
                'count' : 0,
                'got' : 0,
                'free' : 0,
            },

            player.markDirty('activity.hit_box');
        }

        if( !user.hasOwnProperty('pet') ) {
            user.pet = {
                'level': 1,
                'bless': 0,
                'bless_timer': 0,
                'bless_count': 0,
                'skills': [],
                'skill_levels':{'1':1},
                'buff': 0,
            };
            player.markDirty('pet');
        }

        if( !user.hasOwnProperty('special_role') ) {
            user.special_role = {
                'name' : '',
            };
            player.markDirty('special_role');
        }

        if( !user.hasOwnProperty('cloud_shop') ) {
            user.cloud_shop = {
                'score':0,
                'exchange':0,
                'buys':{},
            };

            player.markDirty('cloud_shop');
        }

        if( !user.activity.hasOwnProperty('cost_gift') ) {
            user.activity.cost_gift = {
                'cash' : 0,
                'time' : 0,
                'got' : {},
                'extra_got' : {},
            };

            player.markDirty('activity.cost_gift');
        }

        if( !user.activity.hasOwnProperty('charge_feed') ) {
            user.activity.charge_feed = {
                'score': 0,
                'time': 0,
                'cost' : 0,
                'exchange' : 0,
                'got' : {},
            };

            player.markDirty('activity.charge_feed');
        }

        // 千重楼数据格式修改
        if( typeof(user.tower.current) == 'number' ) {
            user.tower.current = {
                1 : user.tower.current, 
            };
            user.tower.highest = {
                1 : user.tower.highest,
            };

            player.markDirty('tower');
        }

        if( !user.hasOwnProperty('battle_world')) {
            user.battle_world = {
                'buy_energy':0,
                'energy' : 0,
                'energy_time' : 0,
                'move_time' : 0,
                'move':1,
                'support':{},
                'count' : 0,
                'final_reward' : 0,
                'reward' : 0,
                'last_fight_time':0,
            }; 

            player.markDirty('battle_world');
        }

        if( !user.activity.hasOwnProperty('new_charge') ) {
            user.activity.new_charge = {
                'cash':0,          
                'time':0,
                'got' : {
                }, 
            };
            player.markDirty('activity.new_charge');
        }

        if( !user.activity.hasOwnProperty('my_limit') ) {
            user.activity.my_limit = {
                'time' : 0,
                'buy' : {},
            };
            player.markDirty('activity.my_limit');
        }

        if( !user.hasOwnProperty('daily_pay') ) {
            user.daily_pay = {
                'day': 0,
                'cash': 0,
                'reward': 0,
                'month' : '',
                'month_pay': 0,
                'month_day': 0,
            };

            player.markDirty('daily_pay');
        }

        if (!user.hasOwnProperty('daily_vars')) {
            user.daily_vars = {'day':0};
            player.markDirty('daily_vars');
        }

        if( !user.hasOwnProperty('pay_carnival') ) {
            user.pay_carnival = {
                'total_cash': 0,
                'reach_time': 0,
                'award_step': 0,
            };

            player.markDirty('pay_carnival');
        }

        if( !user.hasOwnProperty('huatuo') ) {
            user.huatuo = {
                'xp' : 0,
                'score' : 0,
                'free' : 0,
                'cash' : 0,
                'pellet': 0,
                'quantity' : 0,
                'material' : 0,
            };

            if( common.getDate() == user.mark.day ) {
                // 今天已经登录过的人
                user.huatuo.material = gConfGlobal.HuatuoDailyMaterial
            }

            player.markDirty('huatuo');
        }

        if( !user.league_war.hasOwnProperty('last_fight_time') ) {
            user.league_war.last_fight_time = 0; 
            player.markDirty('league_war.last_fight_time');
        }

        if( !user.activity.hasOwnProperty('daily_pay_rank') ) {
            user.activity.daily_pay_rank = {
                'paid': {},
                'time': 0,
            };

            player.markDirty('activity.daily_pay_rank');
        }

        if( !user.cloud_shop.hasOwnProperty('exchange') ) {
            user.cloud_shop.exchange = 0;
            player.markDirty('cloud_shop.exchange');
        }

        if( !user.activity.hasOwnProperty('pet_gift') ) {
            user.activity.pet_gift = {
                'time': 0,          // 上次活动时间
                'got': {},          // 已经领取
            };
            player.markDirty('activity.pet_gift');
        }

        if( !user.activity.hasOwnProperty('break_egg') ) {
            user.activity.break_egg = {
                'free': 0,          // 每日免费砸蛋次数
                'timer': 0,         // 领奖冷却时间
                'reward': {},       // 奖励
                'got': 0,           // 奖励领取(>0 表示有奖励, <0表示领取完毕)
            };
            player.markDirty('activity.break_egg');
        }

        if( !user.activity.hasOwnProperty('charge_role') ) {
            user.activity.charge_role = {
                'time': 0,          // 上次活动时间
                'cash': 0,          // 已经充值数
                'got': {},          // 已经领取
            };

            player.markDirty('activity.charge_role');
        }

        if( !user.activity.hasOwnProperty('charge_limit') ) {
            user.activity.charge_limit = {
                'time': 0,          // 上次活动时间
                'cash': 0,          // 已经充值数
                'got': {},          // 已经领取
                'buy': {},          // 已经购买
            };

            player.markDirty('activity.charge_limit');
        }

        if( !user.activity.hasOwnProperty('chargegod_limit') ) {
            user.activity.chargegod_limit = {
                'time': 0,          // 上次活动时间
                'cash': 0,          // 已经充值数
                'got': {},          // 已经领取
                'buy': {},          // 已经购买
            };

            player.markDirty('activity.chargegod_limit');
        }

        if( !user.activity.hasOwnProperty('cdkey') ) {
            user.activity.cdkey = {
            };
            player.markDirty('activity.cdkey');
        }

        if( !user.activity.hasOwnProperty('star_gift') ) {
            user.activity.star_gift = {
                'time':0,           // 上次活动时间
                'got':{},           // 领取情况
            };
            player.markDirty('activity.star_gift');
        }

        if( !user.activity.hasOwnProperty('diamond_card') ) {
            user.activity.diamond_card = {
                'free': 0,          // 每日免费次数
                'cash': 0,          // 每日付费次数
                'cards': [],        // 刷新的牌
                'open' : {},        // 翻出的牌
            };
            player.markDirty('activity.diamond_card');
        }

        if( !user.activity.hasOwnProperty('server_payrank') ) {
            user.activity.server_payrank = {
                'time': 0,          // 上次活动时间
                'cash': 0,          // 充值元宝
                'reward': {},       // 全民奖励领取
            };
            player.markDirty('activity.server_payrank');
        }

        if( !user.hasOwnProperty('server_mine') ) {
            user.server_mine = {
                'free' : 0,
            };

            player.markDirty('server_mine');
        }

        if( !user.hasOwnProperty('invite') ) {
            user.invite = {
                'goal' : {},
                'stage' : {},
            };

            player.markDirty('invite');
        }

        if( !user.activity.hasOwnProperty('mystic_shop') ) {
            user.activity.mystic_shop = {};
            player.markDirty('activity.mystic_shop');
        }

        if( !user.activity.hasOwnProperty('lucky_number') ) {
            user.activity.lucky_number =  {
                'got' :  0,
                'selected' : 0,
                'day' : 0,
            };
            player.markDirty('activity.lucky_number');
        }

        if( !user.activity.hasOwnProperty('red_packet') ) {
            user.activity.red_packet= {
                'got' : {},
                'open' : 0,
                'day' :0,

            };
            player.markDirty('activity.red_packet');
        }

        if( !user.activity.hasOwnProperty('year_boss') ) {
            user.activity.year_boss = {
                'join': 0,
                'got_reward':0,
                'cold_time':0,
                'inspire':0,
                'bomb_time':0,
            };
            player.markDirty('activity.year_boss');
        }

        if( !user.activity.hasOwnProperty('rich_send') ) {
            user.activity.rich_send = {
                'time': 0,          // 上次活动时间
                'cash': 0,          // 充值元宝
                'day': common.getDate(),
                'reward': {},       // 全民奖励
            };
            player.markDirty('activity.rich_send');
        }

        if( !user.activity.hasOwnProperty('new_red_packet') ) {
            user.activity.new_red_packet= {
                'got' : {},
                'cash' : 0,
                'open' : 0,
                'day' :0,
            };
            player.markDirty('activity.new_red_packet');
        }

        if( !user.activity.hasOwnProperty('daily_shop_cost') ) {
            user.activity.daily_shop_cost = {
                'cash': 0,
                'day' : 0,
            };
            player.markDirty('activity.daily_shop_cost');
        }

        if( !user.activity.hasOwnProperty('super_card') ) {
            user.activity.super_card = {
                'free': 0,
                'cash': 0,
                'cards': [],
                'open' : {},
            };
            player.markDirty('activity.super_card');
        }

        if( !user.activity.hasOwnProperty('login_invest') ) {
            user.activity.login_invest = {
                'cash' : 0,
                'count' : 0,
                'got' : {},

            };
            player.markDirty('activity.login_invest');
        }

        if( !user.activity.hasOwnProperty('level_invest') ) {
            user.activity.level_invest = {
                'cash' : 0,
                'got' : {},

            };
            player.markDirty('activity.level_invest');
        }

        if( !user.activity.hasOwnProperty('new_first_pay') ) {
            user.activity.new_first_pay = {};

            if( user.activity.first_pay && (1 == user.activity.first_pay) ) {
                var rewardCashs = Object.keys(gConfAvNewFirstPay);
                rewardCashs.sort(function(a, b) { return a - b; });
                var rewardCash = +rewardCashs[0];
                user.activity.new_first_pay[rewardCash] = 0;
            }

            player.markDirty('activity.new_first_pay');
         
        }

        if( !user.activity.hasOwnProperty('new_forge_level') ) {
            user.activity.new_forge_level = {
                'equip' :{
                    'weapon' : 0,  
                    'armor' : 0,
                    'accessory' : 0,
                    'magic' : 0,
                },
                'got' : {},
            };

            if( user.activity.forge_level ) {
                for( var id in user.activity.forge_level ) {
                    user.activity.new_forge_level.got[id] = 1;
                }
            }

            player.markDirty('activity.new_forge_level');
        } 

        if( !user.hasOwnProperty('ride') ) {
            user.ride = {
                'horse_currency' : 0,
                'gold' : 0,
                'horse' : {},
            }; 

            player.markDirty('ride');
            var roles = user.role;
            for( var id in roles ) {
                var role = roles[id];
                if( !role.god )  continue;
                player.addRoleRide(+id, player.addHorse(gConfGlobal.InitalHorseId));
            }
        }

        if( !user.hasOwnProperty('bless_dice') ) {
            user.bless_dice = {
                'score' : 0,
                'count' : 0,
                'free'  : 0,
                'cash'  : 0,
                'cur_round' : 0,
            }; 

            player.markDirty('bless_dice');
        }

        // 羽翼
        var roles = user.role;
        for( var id in roles ) {
            var role = roles[id];
            if( !role.wing && role.god ) {
                player.addRoleWing(+id, gConfGlobal.InitialWingLevel);
            }
        }

        if( !user.activity.hasOwnProperty('dig_treasure') ) {
            user.activity.dig_treasure = {
                'free' : 0,
                'cash' : 0,
                'depth' : 1,
                'axe' : 0,
                'open' : {},
                'time' : 0,
                'day' : 0,
            }; 
            player.markDirty('activity.dig_treasure'); 
        }

        if( !user.activity.hasOwnProperty('pet_cost') ) {
            user.activity.pet_cost = {
                'time' : 0,
                'got' : 0,
                'used' : {},
            }; 
            player.markDirty('activity.pet_cost');
        }

        if( !user.activity.hasOwnProperty('vip_box') ) {
            user.activity.vip_box = {
                'time' : 0,
                'box_count' : {},
            }; 
            player.markDirty('activity.vip_box');
        }

        if( !user.hasOwnProperty('mybattle') ) {
            user.mybattle = {
                'free' : 0,
                'cash' : 0,
                'max' : 0,
                'progress' : {},
            };

            player.markDirty('mybattle'); 
        }

        if( !user.activity.hasOwnProperty('all_gift') ) {
            user.activity.all_gift= {
                'time' : 0,
                'day' : 0,
                'paid' : 0,
                'got' : {
                    'all' : 0,
                    'self' : 0,
                },
            }; 

            player.markDirty('activity.all_gift');
        }

        if( !user.activity.hasOwnProperty('lucky_circle') ) {
            user.activity.lucky_circle =  {
                'score' : 0,
                'items' : [],
                'count' : 0,
                'color' : {
                    'green' : 0,
                    'orange': 0,
                    'purple': 0,
                    'red'   : 0,
                },
                'got' : {
                    'green' : 0,
                    'orange': 0,
                    'purple': 0,
                    'red'   : 0,
                },
                'cash': 0,
                'update_time': 0,
                'time': 0,
                'day' : 0,  
            };

            player.markDirty('activity.lucky_circle');
        }

        if( !user.activity.hasOwnProperty('all_charge') ) {
            user.activity.all_charge =  {
                'cash' : 0,
                'time' : 0,
                'got' : {},
            };

            player.markDirty('activity.all_charge');
        }
        
        if( !user.activity.hasOwnProperty('year_feed_back') ) {
            user.activity.year_feed_back =  {
                'cash' : 0,
                'time' : 0,
                'got' : {},
            };

            player.markDirty('activity.year_feed_back');
        }

        if (!user.activity.hasOwnProperty('national_seven')) {
            user.activity.national_seven = {
                'day' : 0,
                'time' : 0,
                'got' : {},
            };

            player.markDirty('activity.national_seven');
        }

        // 乐元素活动期间记录登录天数
        var loginCountActivitySchedule = findActivitySchedule('logincount');
        if( loginCountActivitySchedule ) {
            if( !user.activity.hasOwnProperty('login_count') ) {
                user.activity.login_count = {
                    'time' : loginCountActivitySchedule.time,
                    'count': 0,
                };

                player.markDirty('activity.login_count');
            }  
            
            var loginCount = user.activity.login_count;
            if( loginCount.time && loginCount.time != loginCountActivitySchedule.time ) {
                loginCount.time = loginCountActivitySchedule.time;
                loginCount.count = 0;

                player.markDirty('activity.login_count');
            }

            if( (0 ==loginCount.count) && (today == user.mark.day) ) {
                loginCount.count = 1; 
            }else if( today != user.mark.day ) {
                loginCount.count += 1; 
            }
            
            player.markDirty('activity.login_count.count');
            
            if (config.ServerId && config.ServerId >= 40) {
                // 乐元素开水推广
                var kaishui_promotion = user.activity.kaishui_promotion;
                if( !user.activity.hasOwnProperty('kaishui_promotion') ) {
                    user.activity.kaishui_promotion = {
                        'time' : loginCountActivitySchedule.time,
                        'task' : {
                            /*id:0*/    // 任务Id以及完成情况
                        },
                    };

                    player.markDirty('activity.kaishui_promotion');
                }  

                if( user.activity.kaishui_promotion.time != loginCountActivitySchedule.time ) {
                    user.activity.kaishui_promotion = {
                        'time' : loginCountActivitySchedule.time,
                        'task' : {
                            /*id:0*/    // 任务Id以及完成情况
                        },
                    };

                    player.markDirty('activity.kaishui_promotion');
                }

                // 开水推广
                doKaiShuiPromotion(player);
            }
        }

        // 国庆七天乐活动
        var nationalSevenActivitySchedule = findActivitySchedule('nationalseven');
        if (nationalSevenActivitySchedule) {
            if (user.activity.national_seven.time != nationalSevenActivitySchedule.time) {
                user.activity.national_seven = {
                    'time' : nationalSevenActivitySchedule.time,
                    'day' : 0,
                    'got' : {},
                };
            }

            var nationalSeven = user.activity.national_seven;
            if (0 == nationalSeven.day) {
                nationalSeven.day = 1;
            } else if (today != user.mark.day) {
                nationalSeven.day += 1;
            }

            player.markDirty('activity.national_seven');
        }

        var leaveDays = common.getDayDiffDays(today, user.mark.day);
        if (!user.mark.day) {
            leaveDays = 0;
        }

        if (today != user.mark.day) {
            var isContinueDay = (leaveDays <= 1) ? true : false;

            // 每日更新
            user.mark.day = today;
            user.mark.trains = 0;
            user.mark.daily_task = 0;
            user.mark.food = 0;
            user.mark.npc_output = 0;
            user.mark.yellow = 0;
            user.mark.league = 0;
            user.mark.login_days += 1;
            user.mark.gold = 0;
            user.mark.p3366 = 0;
            user.mark.blue = 0;
            player.markDirty('mark');

            user.tower.free = 0;
            user.tower.cash = 0;
            player.markDirty('tower.free');
            player.markDirty('tower.cash');

            user.kill.free = 0; 
            user.kill.cash = 0; 
            player.markDirty('kill.free');
            player.markDirty('kill.cash');

            user.prison.free = 0;
            user.prison.cash = 0;
            player.markDirty('prison.free');
            player.markDirty('prison.cash');

            user.rank.free = 0;
            user.rank.cash = 0;
            player.markDirty('rank.free');
            player.markDirty('rank.cash');

            user.mine.occupied = 0;
            user.mine.cash = 0;
            player.markDirty('mine.occupied');
            player.markDirty('mine.cash');

            user.daily_task = {};
            player.markDirty('daily_task');

            user.status.food += +gConfGlobal.DailyFood;
            player.markDirty('status.food');

            user.combine.got = 0;
            user.combine.combined = 0;
            player.markDirty('combine.got');
            player.markDirty('combine.combined');

            user.business.back = 0;
            player.markDirty('business.back');
            
            user.wheel.free = 0;
            player.markDirty('wheel.free');

            user.surprise.free = 0;
            player.markDirty('surprise.free');

            user.activity.limit_buy = {};
            player.markDirty('activity.limit_buy');

            user.league_war.buy_energy = 0; 
            player.markDirty('league_war.buy_energy');

            user.tomb.kill = [0,0,0];
            user.tomb.dig = [0,0,0];
            user.tomb.got = [0,0,0];
            player.markDirty('tomb');

            user.forge.today = 0;           
            player.markDirty('forge.today');

            user.activity.western.back = 0;
            player.markDirty('activity.western.back');

            user.activity.group_on.buy = 0;
            player.markDirty('activity.group_on.buy');

            user.black_shop.limit_sell = {}; 
            player.markDirty('black_shop.limit_sell');

            user.battle_world.buy_energy = 0;
            player.markDirty('battle_world.buy_energy');

            user.huatuo.free = 0;
            user.huatuo.cash = 0;
            player.markDirty('huatuo');

            user.activity.break_egg.free = 0;
            player.markDirty('activity.break_egg.free');

            user.activity.diamond_card.free = 0;
            player.markDirty('activity.diamond_card.free');
            
            user.server_mine.free = 0;
            player.markDirty('server_mine');

            user.activity.mystic_shop = {};
            player.markDirty('activity.mystic_shop');

            user.activity.facebook_feed = 0;
            player.markDirty('activity.facebook_feed');
            
            if( user.activity.daily_shop_cost.day != today ) {
                user.activity.daily_shop_cost = {
                    'cash': 0,
                    'day' : today,
                };
                player.markDirty('activity.daily_shop_cost');
            }

            user.activity.super_card.free = 0;
            player.markDirty('activity.super_card.free');

            user.activity.dig_treasure.free = 0;
            player.markDirty('activity.dig_treasure.free');

            user.activity.dig_treasure.cash = 0;
            player.markDirty('activity.dig_treasure.cash');

            user.ride.gold = 0;
            player.markDirty('ride.gold');

            user.mybattle.free = 0;
            player.markDirty('mybattle.free');

            user.mybattle.cash = 0;
            player.markDirty('mybattle.cash');

            user.lottery.day = today; 
            user.lottery.count = 0;
            user.lottery.got = 0;
            player.markDirty('lottery.day');
            player.markDirty('lottery.count');
            player.markDirty('lottery.got');

            if( user.activity.charge_feed ) {
                user.activity.charge_feed.got = {}; 
                player.markDirty('activity.charge_feed.got');
            }

            user.bless_dice.count = 0;
            user.bless_dice.free = 0;
            player.markDirty('bless_dice.count');
            player.markDirty('bless_dice.free');

            user.activity.lucky_circle.cash = 0;
            user.activity.lucky_circle.color = {
                'green' : 0,
                'orange': 0,
                'purple': 0,
                'red'   : 0,
            };
            user.activity.lucky_circle.got = {
                'green' : 0,
                'orange': 0,
                'purple': 0,
                'red'   : 0,
            };
            user.activity.lucky_circle.day = today;
            user.activity.lucky_circle.count = 0;
            player.markDirty('activity.lucky_circle.cash');
            player.markDirty('activity.lucky_circle.color');
            player.markDirty('activity.lucky_circle.got');
            player.markDirty('activity.lucky_circle.day');
            player.markDirty('activity.lucky_circle.count');

            //更新每日签到数据
            var sign = user.sign;
            var nowDate = common.getDateString();
            var dayDiff = 0; 
            if( sign.first ) {
                dayDiff = common.getDayDiff(nowDate, sign.first); 
            }
            
            if( dayDiff >= +gConfGlobal.SignDayLimit ) {
                user.sign.first = 0;
                user.sign.records = 0;
                user.sign.count = 0;
                user.sign.current = 0;
                user.sign.got = {                 
                        '5' :0,
                        '10':0,
                        '15':0,
                        '20':0,
                        '25':0,
                };
                
                player.markDirty('sign');
            }else {
                sign.current = dayDiff;
                player.markDirty('sign.current');
            }

            //更新连续登陆数据
            var login = user.login;
            var dayDiff = common.getDayDiff(nowDate, login.first); 
            if( login.count != dayDiff 
                || login.count >= +gConfGlobal.LoginDayLimit ) {
                user.login.first = 0;
                user.login.count = 1;
                user.login.got = {
                    '1':0,
                    '2':0,
                    '3':0,
                    '4':0,
                    '5':0,
                };
                login.first = nowDate; 
            }

            if( dayDiff >= 0  && login.count == dayDiff ) {
                login.count += 1;
            }

            player.markDirty('login');

            // 天天爱转轮 
            var nowTime = common.getTime();
            var serverStartDate = new Date(gConfGlobalServer.ServerStartTime*1000);
            var serverStartTime = new Date(serverStartDate.getFullYear(), serverStartDate.getMonth(), serverStartDate.getDate(),0,0,0)/1000;
            if( nowTime > serverStartTime + gConfGlobal.DayWheelOpenDays * 86400 ) {
                var dayWheel = user.day_wheel;
                if( !isContinueDay ) {
                    dayWheel.update_count = 1; 
                    dayWheel.lottery_count = 1;
                    dayWheel.reward_id = 1;
                }else {
                    dayWheel.update_count += 1; 
                    dayWheel.lottery_count += 1;

                    if( dayWheel.update_count >= gConfGlobal.DayWheelAutoRefreshDay ) {
                        dayWheel.update_count = 1; 
                        var weights = {};
                        for( var rewardId in gConfDayWheelReward ) {
                            if( (dayWheel.reward_id == +rewardId) || (1 == +rewardId) ) {
                                continue; 
                            } 

                            weights[rewardId] = gConfDayWheelReward[rewardId].Weight;
                        }

                        dayWheel.reward_id = +common.wRand(weights);
                    }

                }

                dayWheel.free = 0;
                dayWheel.cash = 0;
                player.markDirty('day_wheel');
            }

            // 三顾茅庐
            var visitCottage = user.activity.visit_cottage;
            if( !visitCottage.got && visitCottage.visit ) {
                if( !isContinueDay ) {
                    // 不连续登陆时 
                    if( !visitCottage.got && (visitCottage.count < 3) ) {
                        visitCottage.cash = 1;
                        player.markDirty('activity.visit_cottage.cash');
                    }

                }else {
                    // 连续登陆 
                    if( !visitCottage.got && !visitCottage.cash ) {
                        visitCottage.count += 1; 

                        if( visitCottage.count <= 3 ) {
                            visitCottage.free = 0;
                        }else {
                            visitCottage.free = 1; 
                        }

                        player.markDirty('activity.visit_cottage.count');
                        player.markDirty('activity.visit_cottage.free');
                    }
                }        

                if( (visitCottage.count > 3) && (visitCottage.visit < 3) ) {
                    // 连续登陆超过3天,且拜访次数少于3次 
                    visitCottage.cash = 1;
                    player.markDirty('activity.visit_cottage.cash');
                }
            }

            // 砸箱子
            if( !user.activity.hit_box.got ) {
                user.activity.hit_box.free = 0;
                player.markDirty('activity.hit_box.free');
            }
                
            // 幸运数字
            if( findActivitySchedule('luckynumber') ) {
                user.activity.lucky_number.got = 0; 
                user.activity.lucky_number.selected = 0;
                user.activity.lucky_number.day = today;
                player.markDirty('activity.lucky_number');
            }     

            // 新年红包
            user.activity.red_packet.open = 0; 
            player.markDirty('activity.red_packet.open');
            if( findActivitySchedule('redpacket') ) {
                user.activity.red_packet.got = {}; 
                user.activity.red_packet.open = 0; 
                user.activity.red_packet.day = today; 
                player.markDirty('activity.red_packet');
            }

            // 新区红包
            user.activity.new_red_packet.open = 0; 
            player.markDirty('activity.new_red_packet.open');
            if( findActivitySchedule('newredpacket') ) {
                user.activity.new_red_packet.got = {};
                user.activity.new_red_packet.cash = 0;
                user.activity.new_red_packet.open = 0; 
                user.activity.new_red_packet.day = today; 
                player.markDirty('activity.new_red_packet');
            }

            // 登陆投资
            if( user.activity.login_invest.cash ) {
                user.activity.login_invest.count += 1; 
                player.markDirty('activity.login_invest.count');
            }

            // 重置每日副本信息
            user.league_duplicate.inspire = 0;
            user.league_duplicate.attack_times = 0;
            user.league_duplicate.buy_times = 0;
            player.markDirty('league_duplicate');
        }

        // 处理重返三国活动
        var returnLevelupNeedAddLoginDays = (leaveDays >= 1) ? true : false;
        var activityReturnLevelup = player.getActivity('returnlevelup', {onInit:function(key, activity) {
            activity.leave_days = leaveDays;
            activity.login_days = 1;
            returnLevelupNeedAddLoginDays = false;
        }});

        if (activityReturnLevelup && returnLevelupNeedAddLoginDays) {
            addAttrValue(activityReturnLevelup, 'login_days', 1);
            player.saveActivityValue('returnlevelup', 'login_days');
        }


        // 检查包裹,删除过期物品
        player.checkInventory();
        
        //检查武将
        player.checkRole();

        // 检查武将,装备数据
        player.checkRoleEquip();

        // 更新等级
        player.addXp(0);

        //更新战斗力
        player.roleDirty = true;
        player.getFightForce();

        //更新vip
        player.getVip();

        // 更新成就
        player.getAchievements(true);
        
        resp.data = player.user;
        
        //更新world数据
        player.updateWorld();

        var worldReq = { uid: req.uid, mod: 'league', act: 'update_login', args: {}};
        var worldResp = {};
        requestWorld(worldReq, worldResp);

        //记录
        reportQQ('login', {'opuid': req.uid, 'level':user.status.level}, user.info.platform);

        //RoleLogin|iEventId|iWorldId|iUin|dtEventTime|vClientIp|vZoneId|iRoleId|vRoleName|
        //iRoleLevel|iRoleExp|iRepute|iVipLevel|iMoney|iAccumDeposit|iAccumConsume|iGamePoints|
        //dtCreateTime|iOnlineTotalTime|iLoginWay
        writeRecord(util.format('RoleLogin|%s|%d|%s|%s|%s|0|%d|RoleName|%d|%d|%d|%d|%d|0|0|0|%s|%d|0',
            player.action.getEvent(), config.ServerId, player.openid, Date.stdFormatedString(), player.clientIP, player.uid, 
            user.status.level, user.status.xp, user.status.fight_force, user.status.vip, user.status.cash, 
            Date.createFromStamp(user.info.create).stdFormatedString(), user.mark.online_time||0));

    }while(false);

    if( newVersion ) {
        resp.version = 1;
    }

    if( gConfGlobalServer.FirstServerWarTime ) {
        // 第一次群雄争霸开启时间
        resp.data.server_war_first_time = gConfGlobalServer.FirstServerWarTime;
    }
    
    var serverStartTime = new Date(gConfGlobalServer.ServerStartTime * 1000);
    var serverStartDate = new Date(serverStartTime.getFullYear(), serverStartTime.getMonth(),
                        serverStartTime.getDate(), 0, 0, 0);
    if( gConfGlobal.BattleWorldOpenDays ) {
        // 第一次决战天下距离开服时间n天后的下一个星期天开启
        var firstBattleWorldTime = serverStartDate/1000 + 
            gConfGlobal.BattleWorldOpenDays * 86400;
        var firstBattleWorldDate = new Date(firstBattleWorldTime * 1000);

        var dayOfWeek = firstBattleWorldDate.getDay();
        var daysToNextSunDay = (dayOfWeek >= 1) ? (7 - dayOfWeek) : 0;
 
        firstBattleWorldTime = new Date(firstBattleWorldDate.getFullYear(), 
            firstBattleWorldDate.getMonth(), firstBattleWorldDate.getDate(), 0, 0, 0) / 1000; 

        firstBattleWorldTime += daysToNextSunDay * 86400 + 3600 * gConfBattleWorldSchedule.register.StartTime;

        resp.data.battle_world_first_time = firstBattleWorldTime;
    }

    resp.data.max_level = gUserInfo.maxLevel || 120;
    resp.data.data_holder = gDataHolder.data;
    resp.data.sid = config.ServerId;

    onHandled();
}

exports.logout = function(player, req, resp, onHandled){
    gPlayers.unload(player.uid);
    onHandled();
}

exports.tutorial = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.step) ) {
            resp.code = 1; resp.desc = 'no valid args';
        }
        
        var step = +req.args.step;
        if( !player.user.mark.tutorial ) {
            resp.code = 1; resp.desc = 'step error';
        }

        player.user.mark.tutorial = step;

        player.markDirty('mark.tutorial');

    }while(false);
    
    onHandled();
}

exports.npc_harvest = function(player, req, resp, onHandled){
    do{
        var user = player.user;
        var mark = user.mark;
        var times = +mark.npc_output;

        if( times >= +gConfGlobal.PersonOutPutTimes ) {
            resp.code = 1; resp.desc = 'not enough times'; break;
        }

        var status = user.status;
        var levelConf = gConfLevel[status.level];
        if( !levelConf ) {
            resp.code = 1; resp.desc = 'level error'; break;
        }

        mark.npc_output += 1; 

        var addGold = +levelConf.PersonOutPut;
        status.gold += addGold; 

        player.markDirty('status.gold');
        player.markDirty('mark.npc_output');

        player.doDailyTask(gConfDailyTask.NPC);

        resp.daily_task = gConfDailyTask.NPC;
        resp.data.times = +mark.npc_output;
        resp.data.gold = addGold; 

    }while(false);
    onHandled();
}

exports.sign = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var isCash = (+req.args.cash > 0) ? true: false;
        var now = common.getDateString();

        var user = player.user;
        var sign = user.sign;
        
        if( !sign.first ) {
            sign.first = now; 
            player.markDirty('sign.first');
        }

        var dayDiff = common.getDayDiff(now, sign.first); 
        var max = +gConfGlobal.SignDayLimit; 

        if( dayDiff >= max ) {
            resp.code = 1; resp.desc = 'over max day'; break;
        }

        if( sign.count >= max ) {
            resp.code = 1; resp.desc = 'not permitted'; break;
        }

        var costCash = 0;
        if( isCash ) {
            costCash = +gConfGlobal.SignOnceCash;
            if( user.status.cash < costCash ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            } 
            
            var isExited = false;
            for( var i =1; i < dayDiff; i++ ) {
                var diff = 1<<i;
                if( !(sign.records & diff ) ) {
                    sign.records |= diff; 
                    isExited = true;
                    break;
                } 
            }
            
            if( !isExited ) {
                resp.code = 1; resp.desc = 'not permitted'; break;
            }            

            player.costResource('cash', costCash);
        }else {
            if( sign.records & (1<<dayDiff) ) {
                resp.code = 1; resp.desc = 'already signed'; break;
            }

            sign.records |= (1<<dayDiff);
        }

        sign.count += 1;

        player.markDirty('sign.records');
        player.markDirty('sign.count');
        
        resp.data.cash = -costCash; 
        resp.data.count = sign.count; 
        resp.data.records = sign.records;

    }while(false);
    onHandled();
}

exports.get_sign_reward = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.times) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var times = +req.args.times;

        var user = player.user;
        var sign = user.sign;

        var now = common.getDateString();
        var dayDiff = common.getDayDiff(now, sign.first); 
        var max = +gConfGlobal.SignDayLimit; 

        if( dayDiff >= max ) {
            resp.code = 1; resp.desc = 'do not do this again'; break;
        }

        if( !(times in sign.got) || times > sign.count ) {
            resp.code = 1; resp.desc = 'not valid times'; break;
        }

        if( sign.got[times] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        var signConf = gConfSign[times];
        if( !signConf ) {
            resp.code = 1; resp.desc = 'no valid times'; break;
        }
        
        sign.got[times] = 1;

        var addGold = signConf.Gold;
        var addHonor = signConf.Honor;

        if( user.status.vip ) {
            addGold *= 2;
            addHonor *= 2;
        }

        user.status.gold += addGold;
        user.status.honor += addHonor;
        
        player.markDirty('status.gold');
        player.markDirty('status.honor');

        var awards =[];
        //获取material 奖励
        var award = signConf.Award1;
        if( award ) {
            awards.push(award);
            if( user.status.vip ) {
                awards.push(award);
            }
            awards = player.addAwards(awards); 
        } 
        
        player.markDirty('sign.got');

        resp.data.gold = addGold; 
        resp.data.honor = addHonor;
        resp.data.awards = awards;

    }while(false);

    onHandled();
}

exports.get_login_reward = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.day) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var day = +req.args.day;

        var user = player.user;
        var login = user.login;

        var now = common.getDateString();
        var dayDiff = common.getDayDiff(now, login.first); 
        var max = +gConfGlobal.LoginDayLimit; 

        if( dayDiff >= max ) {
            resp.code = 1; resp.desc = 'do not do this again'; break;
        }

        if( !(day in login.got) || day > login.count ) {
            resp.code = 1; resp.desc = 'day error'; break;
        }
        
        var loginConf = gConfLogin[day];
        if( !loginConf ) {
            resp.code = 1; resp.desc = 'day error'; break;
        }

        if( login.got[day] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        login.got[day] = 1;

        var addHonor = loginConf.Honor;
        var addGold = loginConf.Gold;
        if( user.status.vip ) {
            addHonor *= 2;
            addGold *= 2;
        }

        user.status.honor += addHonor;
        user.status.gold += addGold;

        //获取material 奖励
        var awards = [];
        var award = loginConf.Award1;
        if( award ) {
            awards.push(award);
            if( user.status.vip ) {
                awards.push(award);
            }
            awards = player.addAwards(awards); 
        }

        player.markDirty('status.gold');
        player.markDirty('status.honor');

        player.markDirty('login.got');

        resp.data.gold = addGold; 
        resp.data.honor = addHonor; 
        resp.data.awards = awards;

    }while(false);

    onHandled();
}

exports.get_vip_reward = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.vip) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var vip = parseInt(req.args.vip);

        var user = player.user;
        var vipConf = gConfVip[vip];
        if( !vipConf ) {
            resp.code = 1; resp.desc = 'vip error'; break;
        }

        if( user.status.vip < vip ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        if( user.activity.vip_reward >= vip ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        var addGold = vipConf.Gold;
        var addFood = vipConf.Food;

        var awards = [];
        if( vipConf.Award1 ) {
            awards.push(vipConf.Award1);
        }

        if( vipConf.Award2 ) {
            awards.push(vipConf.Award2);
        }

        if( vipConf.Award3 ) {
            awards.push(vipConf.Award3);
        }

        awards = player.addAwards(awards); 
        
        user.status.gold += addGold;
        player.markDirty('status.gold');

        user.activity.vip_reward = vip;
        player.markDirty('activity.vip_reward');

        resp.data.gold = addGold; 
        resp.data.food = addFood; 
        resp.data.awards = awards;

    }while(false);

    onHandled();
}

exports.invite = function(player, req, resp, onHandled){
    do{
        if( player.user.status.level < +gConfDailyTask[gConfDailyTask.Invite].Level ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        player.doDailyTask(gConfDailyTask.Invite);
        resp.daily_task = gConfDailyTask.Invite;
    }while(false);
    
    onHandled();
}

exports.get_status = function(player, req, resp, onHandled){
    var newPlayer = new Player(req.uid);
    newPlayer.init({'status':1, }, function(succ) {
        do {
            if( !succ ) {
                resp.code = 1; resp.desc = 'player.init'; break;
            }

            resp.data.gold = newPlayer.user.status.gold;
            resp.data.xp = newPlayer.user.status.xp;
        } while(false);

        onHandled();
    });
}

exports.get_seven_days_reward = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.day) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var day = +req.args.day;

        var user = player.user;
        var mark = user.mark;

        if( day <= user.activity.seven_days || day > mark.login_days ) {
            resp.code = 1; resp.desc = 'day error'; break;
        }
        
        var avSeven = gConfAvSeven[day];
        if( !avSeven ) {
            resp.code = 1; resp.desc = 'day error'; break;
        }

        user.activity.seven_days = day;

        var addHonor = avSeven.Honor;
        var addGold = avSeven.Gold;
        var awards = [];

        user.status.honor += addHonor;
        user.status.gold += addGold;
        //获取material 奖励
        var award = avSeven.Award1;
        if( award ) {
            awards.push(award);
            awards = player.addAwards(awards); 
        }

        player.markDirty('status.gold');
        player.markDirty('status.honor');

        player.markDirty('activity.seven_days');

        resp.data.gold = addGold; 
        resp.data.honor = addHonor; 
        resp.data.awards = awards;

    }while(false);
    onHandled();
}

exports.buy_gold = function(player, req, resp, onHandled ) {
    do {
        var user = player.user;

        var canBuy = gConfGlobal.BuyGoldLimit;
        if( user.status.vip ) {
            canBuy += gConfVip[user.status.vip].BuyGold;
        }

        if( user.mark.gold >= canBuy ) {
            resp.code = 1; resp.desc = 'no more to buy'; break;
        }

        var confBuy = gConfBuy[user.mark.gold + 1]; 
        if( !confBuy ) { 
            resp.code = 1; resp.desc = 'no more to buy'; break;
        }   
            
        var costCash = +confBuy.CashGold;
        if( !costCash ) { 
            resp.code = 1; resp.desc = 'no more to buy'; break;
        }   

        var addGold = +gConfLevel[user.status.level].GoldBuy;
        if( !addGold ) { 
            resp.code = 1; resp.desc = 'no more to buy'; break;
        }

        if (!player.costResource('cash', costCash, user.mark.gold)) {
            resp.code = 1; resp.desc = 'not enough cash';break;
        }

        user.status.gold += addGold;
        player.markDirty('status.gold');

        user.mark.gold += 1;
        player.markDirty('mark.gold');

        resp.data.cash = -costCash;
        resp.data.gold = addGold;

    }while(false);

    onHandled();
}

exports.get_day_wheel = function(player, req, resp, onHandled){
    do{
        var isCash = req.args.cash ? 1 : 0;

        var nowTime = common.getTime();
        var serverStartDate = new Date(gConfGlobalServer.ServerStartTime*1000);
        var serverStartTime = new Date(serverStartDate.getFullYear(), serverStartDate.getMonth(), serverStartDate.getDate(),0,0,0)/1000;
        if( nowTime < serverStartTime + gConfGlobal.DayWheelOpenDays * 86400 ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var dayWheel = user.day_wheel;
        if( user.status.level < gConfGlobal.DayWheelOpenLevelLimit ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        if( (1 == dayWheel.reward_id) && (0 == dayWheel.lottery_count) ) {
            dayWheel.update_count = 1;
            dayWheel.lottery_count = 1;
            dayWheel.reward_id = 1;
            player.markDirty('day_wheel');
        }

        if( isCash ) {
            if( !player.costResource('cash', gConfGlobal.DayWheelRefreshCash) ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            } 

            var weights = {};
            for( var rewardId in gConfDayWheelReward ) {
                if( (dayWheel.reward_id == +rewardId) || (1 == +rewardId) ) {
                    continue; 
                } 

                weights[rewardId] = gConfDayWheelReward[rewardId].Weight;
            }

            dayWheel.reward_id = +common.wRand(weights);
            player.markDirty('day_wheel.reward_id');

            resp.data.cash = -gConfGlobal.DayWheelRefreshCash;
        }

        resp.data.day_wheel = dayWheel;
    }while(false);
    onHandled();
}

exports.get_day_wheel_reward = function(player, req, resp, onHandled){
    do{

        var isCash = req.args.cash ? 1 : 0;

        var user = player.user;
        var dayWheel = user.day_wheel;
        if( user.status.level < gConfGlobal.DayWheelOpenLevelLimit ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var rewardId = dayWheel.reward_id;
        if( isCash ) {
            var confBuy = gConfBuy[dayWheel.cash + 1];
            if( !confBuy ) {
                resp.code = 1; resp.desc = 'no cash time'; break;
            } 
            
            var costCash = confBuy.CashDayWheel;
            if( !costCash ) {
                resp.code = 1; resp.desc = 'no cash time'; break;
            }
            
            if( !player.costResource('cash', costCash) ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }

            dayWheel.cash += 1;
            player.markDirty('day_wheel.cash');

            resp.data.cash = -costCash;
        }else {
            var continueDays = dayWheel.lottery_count;
            var days = [];
            for( var day in gConfDayWheel ) {
                days.push(+day);
            }
             
            days = days.sort(function(a, b) {return (b - a); });
            for( var i = 0, len = days.length; i < len; i++ ) {
                if( continueDays >= days[i] ) {
                    continueDays = days[i]; 
                    break;
                } 
            }
            
            if( !gConfDayWheel[continueDays] ) {
                resp.code = 1; resp.desc = 'invalid day'; break;
            }

            if( dayWheel.free >= gConfDayWheel[continueDays].FreeNum ) {
                resp.code = 1; resp.desc = 'no free'; break;
            }

            dayWheel.free += 1;
            player.markDirty('day_wheel.free');
        }
         
        var dayWheelRewardConf = gConfDayWheelReward[rewardId];
        var weights = {};
        for( var i = 1; i <= 8; i++ ) {
            weights[i] = dayWheelRewardConf['Weight' + i];           
        }
        
        var awardsId = +common.wRand(weights);
        resp.data.awards = player.addAwards([dayWheelRewardConf['Award'+awardsId]]);
        resp.data.id = awardsId;

    }while(false);

    onHandled();
}

exports.get_daily_pay = function(player, req, resp, onHandled){
    do{
        if (!player.dailyPayIsOpen()) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        player.updateDailyPay();
        player.updateDailyPayMonth();

        var user = player.user;
        resp.data.daily_pay = user.daily_pay;
    }while(false);

    onHandled();
}

exports.get_daily_pay_reward = function(player, req, resp, onHandled){
    do{
        var isMonth = req.args.month ? 1 : 0;
        var dailyPay = player.user.daily_pay;

        var awards = [];
        if( isMonth ) {
            if( dailyPay.month_pay < gConfGlobal.DailyPayMonthNum ) {
                resp.code = 1; resp.desc = 'not reach'; break;
            }

            player.updateDailyPayMonth(true);
            awards = [gConfDailyPay.month.Award1, gConfDailyPay.month.Award2, 
                        gConfDailyPay.month.Award3];
        }else{
            if( dailyPay.reward ) {
                resp.code = 1; resp.desc = 'got'; break;
            }

            if( dailyPay.cash < gConfGlobal.DailyPayCashMin ) {
                resp.code = 1; resp.desc = 'not reach'; break;
            }

            dailyPay.reward = 1;
            awards = [gConfDailyPay.day.Award1, gConfDailyPay.day.Award2, 
                        gConfDailyPay.day.Award3];
        }
        player.markDirty('daily_pay');
        resp.data.awards = player.addAwards(awards);
        resp.data.daily_pay = dailyPay;
    }while(false);

    onHandled();
}

exports.pay_carnival_get = function(player, req, resp, onHandled){
    do{
        if (!player.checkPayCarnival()) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        resp.data.pay_carnival = player.user.pay_carnival;
        resp.data.daily_vars = player.getDailyVars('cost_cash', 'pay_carnival_award');
    }while(false);

    onHandled();
}

exports.pay_carnival_award = function(player, req, resp, onHandled) {
    do {
        if (isNaN(req.args.id) || isNaN(req.args.step)) {
            resp.code = 1; resp.desc = 'arg id invalid'; break;
        }

        if (!player.checkPayCarnival()) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var id = +req.args.id;
        var step = +req.args.step;

        var payCarnival = player.user.pay_carnival;

        if (!payCarnival.reach_time) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        if (step != payCarnival.award_step) {
            resp.code = 1; resp.desc = 'step mismatch'; break;
        }

        var awards = [];
        if (1 == step) { //充值奖励
            var avConf = gConfAvPayCarnival[id];
            if (!avConf) {
                resp.code = 1; resp.desc = 'id invalid'; break;
            }

            for (var i = 1; i <= 3; ++i) {
                var award = avConf['Award'+i];
                if (award) {
                    awards.push(award);
                }
            }

            payCarnival.award_step = 2;
            player.markDirty('pay_carnival.award_step');

        } else if (2 == step) { //每日消费奖励
            if (player.getDailyVar('pay_carnival_award')) {
                resp.code = 1; resp.desc = 'got'; break;
            }

            if (player.getDailyVar('cost_cash') < gConfGlobal.PayCarnivalDailyCost) {
                resp.code = 1; resp.desc = 'cost not reach'; break;
            }

            var avConf = gConfAvPayCarnivalCost[id];
            if (!avConf) {
                resp.code = 1; resp.desc = 'id invalid'; break;
            }

            for (var i = 1; i <= 3; ++i) {
                var award = avConf['Award'+i];
                if (award) {
                    awards.push(award);
                }
            }

            if (player.user.status.vip >= avConf.DoubleVIP) {
                awards = exCloneObj(awards);
                for (var i = 0, len = awards.length; i < len; ++i) {
                    awards[i][2] *= 2;
                }
            }

            player.addDailyVar('pay_carnival_award', 1);
        } else {
            resp.code = 1; resp.desc = 'step invalid'; break;
        }

        resp.data.awards = player.addAwards(awards);
    } while (false);

    onHandled();
}

exports.get_invite = function(player, req, resp, onHandled){
    requestWorld(req, resp, function(){
        if( resp.code == 0 ) {
            player.inviteGoal = resp.data.invite;
        }
        onHandled();
    });
}

exports.invite_goal_reward = function(player, req, resp, onHandled){
    do{
        var id = req.args.id;
        var goalConf = gConfInviteGoal[id];
        if( !goalConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
        
        var user = player.user;
        if( user.invite.goal[id] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }
        
        if( (player.inviteGoal[id] || 0 ) < goalConf.Num ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        user.invite.goal[id] = 1;

        player.markDirty('invite.goal');
        resp.data.awards = player.addAwards([goalConf.Award1]);
    }while(false);

    onHandled();
}

exports.invite_reward = function(player, req, resp, onHandled){
    do{
        var id = 1;

        var user = player.user;
        
        if( user.invite.stage[id] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }
        
        var reach = true;
        for( var gid in gConfInviteGoal ) {
            if( !user.invite.goal[gid] ) {
                reach = false;
                break;
            }
        }

        if( !reach ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        var rewardConf = gConfInviteReward[id];

        var awards = [];
        for( var i=1; i<=6; i++ ) {
            awards.push(rewardConf['Award'+i]);
        }

        user.invite.stage[id] = 1;
        player.markDirty('invite.stage');

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.visit_friend = function(player, req, resp, onHandled){
    var friendUid = Math.floor(req.args.id);
    if( isNaN(friendUid) ) {
        resp.code = 1;resp.desc = 'invalid args'; 
        onHandled();
        return;
    }

    requestWorld(req, resp, function(){
        if( 1 == resp.data.update ) {
            onHandled();
            return;
        }

        gDBUser.findOne({_id: friendUid}, {'status':1, 'league_war':1, 'role':1, 'achievements':1}, function(err, doc){
            do {
                if( err || !doc ) {
                    resp.code = 1; resp.desc = 'no player'; break;
                }

                var godRoles = {};
                var roles = doc.role;
                for( var id in roles ) {
                    var role = roles[id];
                    if( !role.god ) {
                        continue; 
                    } 

                    godRoles[id] = role.god;
                }

                resp.data.vip = doc.status.vip;
                resp.data.grade = doc.league_war ?  doc.league_war.grade_level : 0;
                resp.data.role = godRoles;
                resp.data.achievements = doc.achievements;

            } while(false);

            onHandled();
        });
    });

}

exports.get_friend = function(player, req, resp, onHandled){
    var user = player.user;

    // 等级限制
    var elderSignVisible = user.status.level >= +gConfGlobal.PeriodLevelLimit;
    var insurgencyVisible = user.status.level >= +gConfGlobal.InsurgencyLevelLimit;
    var horoscopefarmVisible = user.status.level >= +gConfGlobal.HoroscopeFarmOpenLevel;
    var assistMineVisible = true;

    // 好友点数限制
    if (player.isFriendPointFull()) {
        insurgencyVisible = false;
        //assistMineVisible = false;
    }

    // 每日次数限制
    if (gAssistMine.getMyCount(player.uid) >= +gConfGlobal.AssistMineDailyTimes) {
        assistMineVisible = false;
    }

    requestWorld(req, resp, function(){
        if( 1 == resp.code ) {
            onHandled();
            return;
        }

        var friend = resp.data.friend 
        var friendInfos = [];
        for( var id in friend.friend ) {
            var friendInfo = gUserInfo.getUser(id);
            friendInfos.push({
                'uid' : id,
                'name' : friendInfo.name,
                'fight_force' : friendInfo.fight_force,
                'level' : friendInfo.level,
                'headpic' : friendInfo.headpic,
                'blue' : friendInfo.blue, 
                'yellow': friendInfo.yellow, 
                'blue_year': friendInfo.blue_year, 
                'yellow_year': friendInfo.yellow_year,

                // 封印是否对当前玩家可见
                'elder_sign': elderSignVisible ? gElderSign.getFriendStatus(id, player.uid) : elderSignVisible,
                // 平乱是否对当前玩家可见
                'insurgency': insurgencyVisible ? (gInsurgency.getFriendSignByUid(player.uid, id) != 0) : insurgencyVisible,
                // 协助开矿
                'assist_mine': assistMineVisible ? gAssistMine.getFriendMine(player, id) : { global:{}, local:{} },
                horoscopefarm_tree: horoscopefarmVisible && 
                        friendInfo.level >= gConfGlobal.HoroscopeFarmOpenLevel && 
                        gHoroscopefarmTree.isUserVisible(player.uid, id),
            }); 
        }

        var shieldInfos = [];
        for( var id in friend.shield ) {
            var shieldInfo = gUserInfo.getUser(id);
            shieldInfos.push({
                'uid' : id,
                'name' : shieldInfo.name,
                'fight_force' : shieldInfo.fight_force,
                'level' : shieldInfo.level,
                'headpic' : shieldInfo.headpic,
                'blue' : shieldInfo.blue, 
                'yellow': shieldInfo.yellow, 
                'blue_year': shieldInfo.blue_year, 
                'yellow_year': shieldInfo.yellow_year, 
            }); 
        }

        var blackInfos = [];
        for( var id in friend.black ) {
            var blackInfo = gUserInfo.getUser(id);
            blackInfos.push({
                'uid' : id,
                'name' : blackInfo.name,
                'fight_force' : blackInfo.fight_force,
                'level' : blackInfo.level,
                'headpic' : blackInfo.headpic,
                'blue' : blackInfo.blue, 
                'yellow': blackInfo.yellow, 
                'blue_year': blackInfo.blue_year, 
                'yellow_year': blackInfo.yellow_year, 
            }); 
        }

        // 返回玩家当天获取的义气值
        resp.data.daily_friend_point = player.user.daily_vars.friend_point || 0;
        // 当天协助次数
        resp.data.daily_friend_count = gAssistMine.getMyCount(player.uid);

        resp.data.friend = friendInfos;
        resp.data.shield = shieldInfos;
        resp.data.black = blackInfos;

        onHandled();
    });
}

exports.apply_friend = function(player, req, resp, onHandled){
    if( isNaN(req.args.id) || (Math.floor(req.args.id) == req.uid) ) {
        resp.code = 1; resp.desc = 'invalid args';
        onHandled();
        return;
    } 
     
    var friendId = Math.floor(req.args.id);
    gDBUser.findOne({_id: friendId}, {'info':1}, function(err, doc){
        if( err || !doc ) {
            resp.data.existed = 0;
            onHandled();
            return;
        }
        
        requestWorld(req, resp, function(){
            resp.data.existed = 1;
            onHandled();
        });
    });
}

exports.handle_apply_friend = function(player, req, resp, onHandled){

    if( isNaN(req.args.id) || (Math.floor(req.args.id) == req.uid) ) {
        resp.code = 1; resp.desc = 'invalid args';
        onHandled();
        return;
    } 
     
    var friendId = Math.floor(req.args.id);
    gDBUser.findOne({_id: friendId}, {'info':1}, function(err, doc){
        if( err || !doc ) {
            resp.code = 1; resp.desc = 'id error'; 
            onHandled();
            return;
        }
        
        requestWorld(req, resp, function(){
            if( resp.data.update || resp.data.blacked 
                || resp.data.friended || resp.data.fulled ) {
                resp.data.succ = 0; 
            }
            onHandled();
        });
    });
}

exports.shield_friend = function(player, req, resp, onHandled){
    if( isNaN(req.args.id) || (Math.floor(req.args.id) == req.uid) ) {
        resp.code = 1; resp.desc = 'invalid args';
        onHandled();
        return;
    } 
     
    var friendId = Math.floor(req.args.id);
    gDBUser.findOne({_id: friendId}, {'info':1, 'status':1}, function(err, doc){
        if( err || !doc ) {
            resp.code = 1; resp.desc = 'id error'; 
            onHandled();
            return;
        }
        
        requestWorld(req, resp, function(){
            if( (0 == resp.code) && !resp.data.update && !resp.data.fulled ) {
                resp.data.shield = {
                    uid:friendId, 
                    level: doc.status.level,
                    headpic:doc.info.headpic, 
                    name:doc.info.un, 
                    fight_force:doc.status.fight_force,
                    blue : doc.info.blue || 0, 
                    yellow : doc.info.yellow || 0, 
                    blue_year : doc.info.blue_year || 0, 
                    yellow_year : doc.info.yellow_year || 0, 
                };
            }

            onHandled();
        });

    });
}

exports.black_friend = function(player, req, resp, onHandled){
    if( isNaN(req.args.id) || (Math.floor(req.args.id) == req.uid) ) {
        resp.code = 1; resp.desc = 'invalid args';
        onHandled();
        return;
    } 
     
    var friendId = Math.floor(req.args.id);
    gDBUser.findOne({_id: friendId}, {'info':1, 'status':1}, function(err, doc){
        if( err || !doc ) {
            resp.code = 1; resp.desc = 'id error'; 
            onHandled();
            return;
        }
         
        requestWorld(req, resp, function(){
            if( (0 == resp.code) && !resp.data.update && !resp.data.fulled ) {
                resp.data.black = {
                    uid:friendId, 
                    level: doc.status.level,
                    headpic:doc.info.headpic, 
                    name:doc.info.un, 
                    fight_force:doc.status.fight_force,
                    blue : doc.info.blue || 0, 
                    yellow : doc.info.yellow || 0, 
                    blue_year : doc.info.blue_year || 0, 
                    yellow_year : doc.info.yellow_year || 0, 
                };
            }

            onHandled();
        });
    });
}

exports.delete_friend = function(player, req, resp, onHandled){
    if( isNaN(req.args.id) || (Math.floor(req.args.id) == req.uid) ) {
        resp.code = 1; resp.desc = 'invalid args';
        onHandled();
        return;
    } 
     
    requestWorld(req, resp, function(){
        onHandled();
    });
}

exports.rename = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.headpic) ) {
            resp.code = 1; resp.desc = 'invalid headpic'; break;
        }

        var name = req.args.name.toString().trim();
        if( name.length == 0 || name == '0' || name.length > 5 
            || name.indexOf('.') >= 0 || name.indexOf('$') >= 0) {
            resp.code = 1; resp.desc = 'invalid name'; break;
        }

        var user = player.user;
        if( user.mark.rename ) {
            resp.code = 1; resp.desc = 'have rename'; break;
        }
          
        user.info.un = req.args.name;
        user.info.headpic = Math.floor(req.args.headpic);
        user.mark.rename = 1; 
        player.markDirty('info.un');
        player.markDirty('info.headpic');
        player.markDirty('mark.rename');
    }while(false);

    onHandled();
}

exports.get_cash = function(player, req, resp, onHandled){
    resp.data.cash = player.user.status.cash;
    onHandled();
}

/**
 * 获取马超宝箱数据
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.get_machao_box = function(player, req, resp, onHandled){
    resp.data.machao_box = player.getMaChaoBox();
    onHandled();
};

/**
 * 义气抽奖
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.exchange_friend_point = function(player, req, resp, onHandled){

    if (player.user.status.level < +gConfGlobal.NewFriendAwardLevelLimit) {
        resp.code = 1; resp.desc = "level limit";
        onHandled();
        return;
    }

    if (player.user.status.level < +gConfGlobal.NewFriendAwardLevelLimit) {
        resp.code = 1; resp.desc = "level limit";
        onHandled();
        return;
    }

    // 判断玩家义气点是否足够
    var userHavePoint = +(player.user.status.friend_point || 0);
    var exCostPoint = +gConfGlobal.NewFriendAwardPointCost;
    if (userHavePoint < exCostPoint) {
        resp.code = 1; resp.desc = "no enough point";
        onHandled();
        return;
    }

    // 扣除义气点
    resp.data.friend_point = -exCostPoint;
    player.addFriendPoint(-exCostPoint);

    // 给玩家添加道具
    var awards = roundAward(gConfFriendPointAwards, 3);
    var awardArr = [];
    awards.forEach(function(award){
        awardArr.push(award.Award);
    });
    resp.data.awards = player.addAwards(awardArr);

    // 更新马超宝箱
    var maBox = player.getMaChaoBox();
    var boxCfg = gConfFriendMaChaoBox[maBox.id];
    var step = +boxCfg.Step;
    maBox.progress = Math.min(maBox.progress + step, +boxCfg.MaxProgress);
    player.markDirty("machao_box.progress");
    resp.data.machao_box = maBox;

    onHandled();
};

/**
 * 领取马超宝箱
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.get_machao_reward = function(player, req, resp, onHandled){
    var isCash = +req.args.iCash;
    if (isNaN(isCash)) {
        resp.code = 1; resp.desc = "parameter error";
        onHandled();
        return;
    }

    if (player.user.status.level < +gConfGlobal.NewFriendAwardLevelLimit) {
        resp.code = 1; resp.desc = "level limit";
        onHandled();
        return;
    }

    do {
        var maBox = player.getMaChaoBox();
        var boxConfig = gConfFriendMaChaoBox[maBox.id];

        var curStep = maBox.progress;
        var needStep = +boxConfig.MaxProgress;
        if (curStep < needStep) {
            resp.code = 1; resp.desc = "not reach step";
            break;
        }

        var maTime = 1;
        if (isCash) {
            var needCash = +boxConfig.Cash;
            if (needCash > player.user.status.cash) {
                resp.code = 1; resp.desc = "not enough cash";
                break;
            }

            //扣除玩家元宝
            if (!player.costResource('cash', needCash)) {
                resp.code = 1; resp.desc = 'cash not enough';
                break;
            }

            maTime = +boxConfig.Time;
        }

        var awards = boxConfig.Awards;
        // 发放多倍奖励
        if (maTime > 1) {
            // 拷贝一个，防止对配置的修改
            awards = JSON.parse(JSON.stringify(awards));
            awards.forEach(function(award){
                award[2] = award[2] * maTime;
            });
        }

        gMessage.addSystemMessage('machao_get', [player.user.info.un, awards[0][2]]);

        resp.data.awards = player.addAwards(awards);
        resp.data.cash = (isCash) ? -needCash : 0;

        // 重置马超宝箱
        player.user.machao_box.id = -1;
        player.markDirty("machao_box.id");

    } while (false);

    onHandled();
};

/**
 * 取消帮助好友平乱
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.insurgency_cancel_help = function(player, req, resp, onHandled){
    do {
        var myUid = req.uid;
        var fUid = +req.args.fuid;
        if (isNaN(fUid)) {
            resp.code = 1; resp.desc = 'invalid parameter'; break;
        }

        if (player.user.status.level < +gConfGlobal.InsurgencyLevelLimit) {
            resp.code = 1;
            resp.desc = "level limit";
            break;
        }

        gInsurgency.blockUser(myUid, fUid);
    } while (false);

    onHandled && onHandled();
};

/**
 * 帮助好友平乱
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.insurgency_battle = function(player, req, resp, onHandled){
    do {
        var fUid = +req.args.fuid;
        if (isNaN(fUid)) {
            resp.code = 1; resp.desc = "invalid parameters"; break;
        }

        if (player.user.status.level < +gConfGlobal.InsurgencyLevelLimit) {
            resp.code = 1;
            resp.desc = "level limit";
            break;
        }

        // 判断好友点数是否达到每日上限
        if (player.isFriendPointFull()) {
            resp.code = 1;
            resp.desc = "point reach top";
            return;
        }

        gInsurgency.battle(player, fUid, function(err, res){
            if (err) {
                resp.code = 0; resp.desc = err; resp.data.code = 1;
            } else {
                resp.data = res;

                if (res.battle.success) {   // 战斗胜利

                    var award;              // 奖励道具
                    var pointGet = 0;       // 奖励义气值

                    // 根据玩家等级查找奖励
                    var playerLevel = player.user.status.level;
                    var maxId;
                    for (var Id in gConfInsurgencyAward) {
                        if (playerLevel <= +gConfInsurgencyAward[Id].Level) {
                            award = gConfInsurgencyAward[Id].Awards;
                            pointGet = +gConfInsurgencyAward[Id].Point;
                            break;
                        }
                        maxId = Id;
                    }
                    if (!award) {
                        award = gConfInsurgencyAward[maxId].Awards;
                        pointGet = +gConfInsurgencyAward[maxId].Point;
                    }

                    // 发放奖励
                    resp.data.awards = player.addAwards(award);
                    var oldPt = player.user.status.friend_point || 0;
                    resp.data.friend_point = player.addFriendPoint(pointGet) - oldPt;
                }
            }

            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
};

/**
 * 协助金矿战斗
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.assist_mine_battle = function(player, req, resp, onHandled){
    do {
        var fUid = +req.args.fuid;  // 好友UID
        var mId = +req.args.id;     // 我的UID
        var mPos = +req.args.pos;   // 金矿位置
        var type = +req.args.type;  // 金矿类型

        // 检查参数
        if (isNaN(fUid) || isNaN(mId) || isNaN(mPos) || isNaN(type)) {
            resp.code = 1; resp.desc = "invalid parameters"; break;
        }

        // 判断好友点数是否达到每日上限
        /* if (player.isFriendPointFull()) {
            resp.code = 1;
            resp.desc = "point reach top";
            return;
        } */

        // 每日次数限制
        if (gAssistMine.getMyCount(player.uid) >= +gConfGlobal.AssistMineDailyTimes) {
            resp.code = 1;
            resp.desc = "daily times limit";
            return;
        }

        gAssistMine.battle(player, player, fUid, type, mId, mPos, function(err, res){
            if (err) {
                resp.code = 0; resp.desc = err; resp.data.code = 1;
            } else {
                resp.data = res;

                var userLevel = player.user.status.level;

                var awardId = _findAwardId(res.hpAtkP);
                if (awardId != -1) {
                    // 计算玩家获取的金币
                    var awards = gConfAssistMineAward[awardId].Factor / 100;
                    if (!isNaN(awards)) {
                        var myMineOutputMax = 0;
                        if (type == 0) { // 本地金矿
                            var mineConf = gConfMine[Math.min(mId, 5)];
                            var outputPerHour = mineConf.OutputPerHour * gConfLevel[userLevel].MineOutputFactor;
                            myMineOutputMax = Math.floor(gConfGlobal.MineMaxOutput * outputPerHour);
                        } else { // 跨服金矿
                            //var quantity = getMineQuantity(mId);
                            //var mineConf = gConfServerMine[quantity];
                            //var outputPerHour = mineConf.OutputPerHour * gConfLevel[userLevel].ServerMineOutputFactor;
                            //myMineOutputMax = Math.floor(gConfGlobal.ServerMineMaxOutput * outputPerHour);
                        }
                        var goldGet = Math.floor(myMineOutputMax * awards);
                        player.user.status.gold += goldGet;
                        player.markDirty("status.gold");

                        resp.data.gold = goldGet;
                    }
                }

                // 添加义气值
                var oldPoint = player.user.status.friend_point || 0;
                resp.data.friend_point = player.addFriendPoint(+gConfGlobal.AssistMineBattleAwardPoint) - oldPoint;
            }

            onHandled && onHandled();
        });

        return;
    } while (false);

    onHandled && onHandled();

    // 根据玩家打掉的血量百分比获取奖励配置ID
    function _findAwardId(hpFk) {
        for (var Id in gConfAssistMineAward) {
            if (hpFk >= gConfAssistMineAward[Id].HpFk) {
                return Id;
            }
        }
        return -1;
    }
};

/**
 * 领取QQ电脑管家新手礼包
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.get_qqpcmgr_new_user_awards = function(player, req, resp, onHandled){
    do {
        if (player.user.status.level < +gConfGlobal.QQPCManagerOpenLevel) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var confObj = gConfQQPCManager[1];
        if (!confObj) {
            resp.code = 1; resp.desc = 'conf error'; break;
        }

        var qqpcmgr_data = player.user.qqpcmgr;
        if (isNaN(qqpcmgr_data.sign_count)) {
            qqpcmgr_data.sign_count = 0;
        }

        if (qqpcmgr_data.new_user_award_time != 0) {
            resp.code = 1; resp.desc = 'already get'; break;
        }

        var daily_signed = player.getDailyVar('qqpcmgr_signed');
        if (daily_signed) {
            resp.data.awards = player.addAwards(confObj.NewUserAwards);
            qqpcmgr_data.new_user_award_time = Date.getStamp();
            player.markDirty("qqpcmgr.new_user_award_time");
            break;
        }

        var url = util.format('http://0.0.0.0:%d?&act=%s&key=%s&openid=%s',
            config.GatewayListen, 'get_qqpcmgr_status', config.GMAuth, player.openid);
        common.httpGet(url, function(data) {
            if (data && data.code == 0) {
                resp.data.awards = player.addAwards(confObj.NewUserAwards);
                qqpcmgr_data.new_user_award_time = Date.getStamp();
                player.markDirty("qqpcmgr.new_user_award_time");
            } else {
                resp.data = {
                    code: 1
                };
            }
            onHandled && onHandled();
        }, true);

        return;
    } while (false);

    onHandled && onHandled();
};

/**
 * 获取QQ电脑管家每日礼包
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.get_qqpcmgr_daily_awards = function(player, req, resp, onHandled){
    do {
        if (player.user.status.level < +gConfGlobal.QQPCManagerOpenLevel) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var confObj = gConfQQPCManager[1];
        if (!confObj) {
            resp.code = 1; resp.desc = 'conf error'; break;
        }

        var daily_signed = player.getDailyVar('qqpcmgr_signed');
        if (daily_signed) {
            resp.code = 1; resp.desc = 'already get'; break;
            break;
        }

        var qqpcmgr_data = player.user.qqpcmgr;
        if (isNaN(qqpcmgr_data.sign_count)) {
            qqpcmgr_data.sign_count = 0;
        }

        if (Date.getDayPassed(qqpcmgr_data.new_user_award_time) == 1) {
            resp.data.awards = player.addAwards(confObj.DailyAwards);
            if (qqpcmgr_data.sign_count != 7) {
                qqpcmgr_data.sign_count += 1;
                player.markDirty('qqpcmgr.sign_count');
            }
            player.setDailyVar('qqpcmgr_signed', 1);
            break;
        }

        var url = util.format('http://0.0.0.0:%d?&act=%s&key=%s&openid=%s',
            config.GatewayListen, 'get_qqpcmgr_status', config.GMAuth, player.openid);
        common.httpGet(url, function(data) {
            if (data && data.code == 0) {
                resp.data.awards = player.addAwards(confObj.DailyAwards);
                if (qqpcmgr_data.sign_count != 7) {
                    qqpcmgr_data.sign_count += 1;
                    player.markDirty('qqpcmgr.sign_count');
                }
                player.setDailyVar('qqpcmgr_signed', 1);
            } else {
                resp.data = {
                    code: 1
                };
            }
            onHandled && onHandled();
        }, true);

        return;
    } while (false);

    onHandled && onHandled();
};

/**
 * 获取QQ电脑管家7日登录礼包
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.get_qqpcmgr_sevenday_awards = function(player, req, resp, onHandled){
    do {
        if (player.user.status.level < +gConfGlobal.QQPCManagerOpenLevel) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var confObj = gConfQQPCManager[1];
        if (!confObj) {
            resp.code = 1; resp.desc = 'conf error'; break;
        }

        var qqpcmgr_data = player.user.qqpcmgr;
        if (isNaN(qqpcmgr_data.sign_count)) {
            qqpcmgr_data.sign_count = 0;
        }

        if (qqpcmgr_data.sign_count != 7) {
            resp.code = 1; resp.desc = 'can not get awards'; break;
        }

        resp.data.awards = player.addAwards(confObj.SevenDayAwards);

        qqpcmgr_data.sign_count = 0;
        player.markDirty('qqpcmgr.sign_count');
    } while (false);

    onHandled && onHandled();
};
